package cn.lanqiao.bigDate.web.security;

import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import cn.lanqiao.common.utils.TokenUtil;
import org.springframework.web.servlet.HandlerInterceptor;

import cn.lanqiao.bigDate.service.sys.LoginService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.net.URLDecoder;
import java.util.Arrays;
import java.util.Set;
import java.util.stream.Collectors;

@Component
public class SecurityInterceptor implements HandlerInterceptor {

	@Autowired
	private LoginService loginService;

	private final String BASEURL="/bigDateWeb";

	@Autowired
	private StringRedisTemplate stringRedisTemplate;

	@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
		if(handler instanceof HandlerMethod){
			HandlerMethod method=(HandlerMethod)handler;
			Security annotation=method.getMethodAnnotation(Security.class);
			if(annotation!=null){
				switch(annotation.value()){
					case PUBLIC:
						return true;
					case PRIVATE:
						return false;
					case PROTECTED:
						if(request.getCookies()==null){
							response.sendRedirect(BASEURL+"/expires");
							return false;
						}
						Set<String> headers= Arrays.stream(request.getCookies()).filter(cookie -> cookie.getName().equals("Authorization")).map(Cookie::getValue).collect(Collectors.toSet());
						String authHeader=null;
						if(headers.size()==1){
							authHeader= URLDecoder.decode((String)headers.toArray()[0],request.getCharacterEncoding());
						}
						if(authHeader==null||!authHeader.startsWith("Bearer ")){
							response.sendRedirect(BASEURL+"/expires");
							return false;
						}
						String token=authHeader.substring(7);
						if(!TokenUtil.verify(token)){
							response.sendRedirect("/bigDateWeb/expires");
							return false;
						}
						if(stringRedisTemplate.opsForSet().isMember("blackList",token)){
							response.sendRedirect(BASEURL+"/expires");
						}
						String url=request.getRequestURI();
						if(url.startsWith(BASEURL)){
							url=url.substring(BASEURL.length());
						}
						String userName=TokenUtil.getUserName(token);
						Set<String> urlList=loginService.getMenuList(userName);
						if(!urlList.contains(url)){
							response.sendRedirect(BASEURL+"/invalidate");
						}
						request.getServletContext().setAttribute("loginName",TokenUtil.getUserName(token));
				}
			}
		}
		return true;
	}

}